#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <cassert>
#include <stdint.h>
#include <cstring>
#include <ctime>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <functional>
#include <sys/epoll.h>
#include <unordered_map>
#include <mutex>
#include <thread>
#include <sys/eventfd.h>
#include <memory>
#include <sys/timerfd.h>
#include <condition_variable>
#include <signal.h>
#include <sys/stat.h>

#define INF 0
#define DBG 1
#define ERR 2

#define DEFAUL_LEVEL ERR

#define LOG(level, format, ...)                                                               \
    do                                                                                        \
    {                                                                                         \
        if (level < DEFAUL_LEVEL)                                                             \
            break;                                                                            \
        time_t t = time(nullptr);                                                             \
        struct tm *lmt = localtime(&t);                                                       \
        char info[32];                                                                        \
        strftime(info, 31, "%H:%M:%S", lmt);                                                  \
        fprintf(stdout, " [%p %s %s:%d] " format "\n", (void*)pthread_self(),info, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define INF_LOG(format, ...) LOG(INF, format, ##__VA_ARGS__)
#define DBG_LOG(format, ...) LOG(DBG, format, ##__VA_ARGS__)
#define ERR_LOG(format, ...) LOG(ERR, format, ##__VA_ARGS__)
int FdInfo(int fd){
    int fd_status = fcntl(fd, F_GETFD);
    if (fd_status == -1 && errno == EBADF) {
        DBG_LOG("文件描述符已经被释放了??");
        return -1;
    }
    return 0;
}

class Channel;
void DebugPrint(Channel* channel);

#define BUFFER_DEFAULT_SIZE 1024
class Buffer
{
private:
    std::vector<char> _buffer; // 缓冲区
    uint64_t _write_idx;       // 写偏移量
    uint64_t _read_idx;        // 读偏移量
public:
    Buffer()
        : _buffer(BUFFER_DEFAULT_SIZE), _write_idx(0), _read_idx(0)
    {
    }
    ~Buffer() {}
    char *Begin() { return &(*_buffer.begin()); }
    // 获取读起始地址位置
    char *ReadPositoin() { return Begin() + _read_idx; };
    // 获取写起始地址位置
    char *WritePosition() { return Begin() + _write_idx; };
    // 获取尾部空闲空间大小       总大小(开) - 写入的位置(闭)
    uint64_t TailIdleSpace() { return _buffer.size() - _write_idx; }
    // 获取头部空闲空间大小
    uint64_t HeadIdleSpace() { return _read_idx; };
    // 获取可读空间大小
    uint64_t ReadAbleSize() { return _write_idx - _read_idx; };
    // 增加读偏移量
    void ReadMoveOffset(uint64_t len)
    {
        if (len == 0) return;
        assert(len <= ReadAbleSize());
        _read_idx += len;
    }
    // 增加写偏移量
    void WriteMoveOffset(uint64_t len)
    {
        _write_idx += len;
    }
    // 检查是否可以写入(移动 + 拷贝)
    void EnsureWriteEnable(uint64_t len)
    {
        // 直接写入就可以
        if (len <= TailIdleSpace())
        {
            return;
        }
        if (len <= TailIdleSpace() + HeadIdleSpace())
        {
            // 需要进行移动
            uint64_t rsz = ReadAbleSize();
            // 拷贝原有的数据，到缓冲区开头
            std::copy(ReadPositoin(), ReadPositoin() + rsz, Begin());
            _read_idx = 0;
            _write_idx = rsz;
        }
        else
        {
            // 需要进行扩容 - 这里我们不想要再进行移动了，因为这样会进行两次拷贝，所以我们直接扩容
            _buffer.resize(_write_idx + len);
            DBG_LOG("resize_size:%ld",_write_idx + len);
        }
    }
    // 写入数据
    void Write(const void *buff, uint64_t len)
    {
        EnsureWriteEnable(len);
        // 不过这里需要注意，我们void*进行+操作，编译器并不知道该加多少，所以需要进行转换
        const char *d = (const char *)buff;
        std::copy(d, d + len, WritePosition());
    }
    void WriteAndPush(const void *buff, uint64_t len)
    {
        Write(buff, len);
        WriteMoveOffset(len);
    }
    void WriteAsString(const std::string &s)
    {
        Write((void *)(&(s[0])), s.size());
    }
    void WriteAsStringPush(const std::string &s)
    {
        WriteAsString(s);
        WriteMoveOffset(s.size());
    }
    void WriteAsBuffer(Buffer &data)
    {
        Write(data.Begin(), data.ReadAbleSize());
    }
    void WriteAsBufferPush(Buffer &data)
    {
        WriteAsBuffer(data);
        WriteMoveOffset(data.ReadAbleSize());
    }
    // 读取数据
    void Read(void *buff, uint64_t len)
    {
        // 只能读取我们已有的数据，超过的话直接报错
        assert(len <= ReadAbleSize());
        std::copy(ReadPositoin(), ReadPositoin() + len, (char *)buff);
    }
    void ReadAndpop(void *buff, uint64_t len)
    {
        Read(buff, len);
        ReadMoveOffset(len);
    }
    std::string ReadAsString(uint64_t len)
    {
        std::string str;
        str.resize(len);
        Read(&str[0], len);
        return str;
    }
    std::string ReadAsStringPop(uint64_t len)
    {
        std::string str = ReadAsString(len);
        ReadMoveOffset(len);
        return str;
    }
    // 专门针对于http协议的获取
    char *FindCRLF()
    {
        // 从一个源地址中开始找 '\n' 这个字符出现的位置，查询的范围大小为多少
        char *res = (char *)memchr(ReadPositoin(), '\n', ReadAbleSize());
        return res;
    }
    // 这里如果没有 '\n'，那么就会返回空，那么读取的位置并不会改变。(需要注意一下)
    // 有些服务器当中，如果没有'\n'，那么就会把剩余的数据返回，但是这样并不是一个完整的数据，我们这里不这样处理。    
    std::string GetLine()
    {
        char *res = FindCRLF();
        if (res == nullptr)
            return "";
        //123456\n
        //这里应该返回的是 +1个大小。
        return ReadAsString(res - ReadPositoin()+1);
    }
    std::string GetLineAndPop()
    {
        std::string str = GetLine();
        // 这里需要注意我们要先读取数据，然后才能让读偏移量改变，不然我们读取数据的时候会提前触发assert。
        if (str.size() > 0) 
            ReadMoveOffset(str.size());
        return str;
    }
    // 清楚数据
    void Clear() { _write_idx = _read_idx = 0; }
};

#define BACK_LOG 1024
class Socket
{
private:
    int _socketfd;

public:
    Socket()
        : _socketfd(-1)
    {
    }
    Socket(int fd)
        : _socketfd(fd)
    {
    }
    int Fd() {return _socketfd;}
    // 创建套接字
    bool Create()
    {
        // int socket(int domin, int type, int protocol)
        _socketfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (_socketfd < 0)
        {
            ERR_LOG("CREATE SOCKET FALSE!!");
            return false;
        }
        return true;
    }
    // 根据ip和端口进行绑定
    bool Bind(const std::string &ip, const uint16_t port)
    {
        // int bind(int socketfd,struct sockaddr* ,socklen_t len)
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = ::htons(port);
        server.sin_addr.s_addr = ::inet_addr(ip.c_str());
        socklen_t len = sizeof(server);
        int ret = ::bind(_socketfd, (struct sockaddr *)(&server), len);
        if (ret < 0)
        {
            ERR_LOG("BIND ERROR");
            return false;
        }
        return true;
    }
    // 监听连接
    bool Listen()
    {
        // int listen(int socketfd,int backlog) - backlog 这是限制同一时刻可以接受的最大连接数
        int ret = ::listen(_socketfd, BACK_LOG);
        if (ret < 0)
        {
            ERR_LOG("LISTEN ERROR!!");
            return false;
        }
        return true;
    }
    // 获取连接 - 这里我们不需要关注对端的ip信息，所以就不传参数了
    int Accept()
    {
        int newfd = ::accept(_socketfd, nullptr,nullptr);
        if (newfd < 0)
        {
            ERR_LOG("ACCEPT ERR!!!");
            return -1;
        }
        // 这里直接返回即可
        return newfd;
    }

    // 建立连接 - 客户端
    bool Connect(const std::string &ip, const uint16_t port)
    {
        // int connect(int socketfd,sockaddr*,socklen_t len)
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = ::htons(port);
        server.sin_addr.s_addr = ::inet_addr(ip.c_str());
        socklen_t len = sizeof(server);
        int ret = ::connect(_socketfd, (struct sockaddr *)(&server), len);
        if (ret < 0)
        {
            ERR_LOG("CONNECT ERROR");
            return false;
        }
        return true;
    }
    // 建立服务端连接
    bool CreateServer(const uint16_t port, const std::string &ip = "0.0.0.0", bool block_flg = false)
    {
        // 1. 建立连接 2. 设置非阻塞 3. 绑定 4. 监听 5. 设置地址可重用
        if (!Create())
            return false;
        if (block_flg)  //默认为阻塞
            NonBlock();
        ReUseAddr();
        if (!Bind(ip, port))
            return false;
        if (!Listen())
            return false;
        return true;
    }
    // 建立客户端连接
    bool CreateClient(const uint16_t port, const std::string &ip)
    {
        if (!Create())
            return false;
        if (!Connect(ip, port))
            return false;
        return true;
    }
    // 发送数据 - 默认都是非阻塞
    ssize_t Send(const void *buf, const uint64_t len, int flg = 0)
    {
        //::send(int socketfd,void* buf,int len,int flags)
        ssize_t ret = ::send(_socketfd, buf, len, flg);
       if (ret <= 0)
        {
            if (errno == EAGAIN || errno == EINTR)
            {
                DBG_LOG("数据还没有准备好/被信号打断");
                return 0;
            }
            else
            {
                ERR_LOG("SEND ERROR");
                return -1;
            }
        }
        // 返回的实际发送的数据个数
        return ret;
    }
    ssize_t SendNonBlock(void *buf, uint64_t len){
        if (len == 0) return 0;
        return Send(buf,len,MSG_DONTWAIT);
    }
    // 接受数据 - 默认都是非阻塞
    ssize_t Recv(void *buf, uint64_t len, int flg = 0)
    {
        ssize_t ret = ::recv(_socketfd, buf, len, flg);
        if (ret <= 0)
        {
            if (errno == EAGAIN || errno == EINTR)
            {
                DBG_LOG("数据还没有准备好/被信号打断");
                return 0;
            }
            else
            {
                ERR_LOG("RECV ERROR");
                return -1;
            }
        }
        //返回实际读到的数据个数
        return ret;
    }
    ssize_t RecvNonBlock(void *buf, uint64_t len){
        if(len == 0) return 0;
        return Recv(buf,len,MSG_DONTWAIT);
    }
    // 设置地址可重用
    void ReUseAddr()
    {
        //int setsockopt(int socketfd,int level,int optname,void* optval,int vallen)
        int val =1;
        setsockopt(_socketfd,SOL_SOCKET,SO_REUSEADDR | SO_REUSEPORT,&val,sizeof(int));
    }
    // 设置非阻塞
    void NonBlock()
    {
        //原来的文件权限
        int fd = ::fcntl(_socketfd,F_GETFL);
        ::fcntl(_socketfd,F_SETFL,fd|O_NONBLOCK);
    }
    // 关闭连接
    void Close()
    {
        if (_socketfd != -1){
            // DBG_LOG("关闭文件描述符: %d",_socketfd);
            ::close(_socketfd);
            _socketfd = -1;
        }        
    }
};
class Poller;
class EventLoop;
class Channel
{
private:
    int _fd;
    uint32_t _event;
    uint32_t _revent;
    EventLoop* _loop;
    using EpollCallBack = std::function<void()>; //这里其实应该有个Connection*的，未来我们Channel中的回调函数都是通过Connection设置的。
    EpollCallBack _read_callback; 
    EpollCallBack _write_callback;
    EpollCallBack _close_callback;
    EpollCallBack _error_callback;
    EpollCallBack _event_callback; //任意事件的回调函数
    //设置需要poller模块的接口 - 这也可以体现出我们设计为 Channel*参数的好处
    //但是当前我们只有Poller的声明，如果需要调用里面的函数的话找不到，所以定义我们需要再poller模块下方进行定义；

public:
    Channel(EventLoop* loop,int fd) :_fd(fd),_event(0),_revent(0), _loop(loop)
        {}
    int Fd() {return _fd;}
    void Update();
    void Remove();    
    uint32_t GetEvents() {return _event;}
    //是否监控了读事件
    bool IfReadEvent() {return ((_event & EPOLLIN) == EPOLLIN);}
    //是否监控了写事件
    bool IfWriteEvent() {return ((_event & EPOLLOUT) == EPOLLOUT);}
    //启动监控写事件 
    void EnableWriteEvent() { _event |= EPOLLOUT; Update();}
    //启动监控读事件 
    void EnableReadEvent() {_event |= EPOLLIN;Update();}
    //删除写事件监控 
    void DelWriteEvent() {_event &= (~EPOLLOUT);Update();} //0010  &= 1101  位运算去掉某个事件
    //删除读事件监控 
    void DelReadEvent() {_event &= (~EPOLLIN);Update();}
    //删除所有事件监控 
    void DelEvents() {_event = 0;Update();}
    //移除监控 - 这个我们需要通过epoller模块的方法来进行设置，现在还实现不了。
    void RemoveEvent() {Remove();};
    EventLoop* Loop() {return _loop;}
    //设置所有的回调函数
    void SetReadCallBack(const EpollCallBack& cb) {_read_callback = cb;}; 
    void SetWriteCallBack(const EpollCallBack& cb) {_write_callback = cb;}; 
    void SetCloseCallBack(const EpollCallBack& cb) { _close_callback = cb;}; 
    void SetErrorCallBack(const EpollCallBack& cb) {_error_callback = cb;}; 
    void SetEventsCallBack(const EpollCallBack& cb) {_event_callback = cb;}; 
    void SetRevents(uint32_t revents) {_revent = revents;}
    //事件处理 - 为了当前fd触发了事件有自己来执行，它知道自己需要执行什么回调函数
    
    void HandlerEvent()
    {
        //revetn就是触发了什么时间
        //其实任意事件只是针对于读或写事件之后才进行的
        if (((_revent & EPOLLIN)==EPOLLIN)|| ((_revent & EPOLLRDHUP)==EPOLLRDHUP) || ((_revent & EPOLLPRI)==EPOLLPRI)){
            //为什么读/写刷新超时时间是在处理完读写之后呢??
            //如果当前的读或写处理的时间很长，执行完之后立马就释放掉了，那不合适，所以我们应该处理完之后立马刷新超时时间。
            if (_read_callback) _read_callback();
        }   
        if (((_revent & EPOLLOUT)==EPOLLOUT)){
            if (_write_callback) _write_callback();
        }else if (((_revent & EPOLLERR)==EPOLLERR)){  //EPOLLERR
            if (_error_callback) _error_callback();
        }
        else if(((_revent & EPOLLHUP)==EPOLLHUP)){ //当异常事件的时候，会直接关闭文件描述符，释放资源，这样就不应该再执行其他的方法了。
            //所以对于异常的事件如果想要刷新超时时间，需要再关闭连接之前刷新。
            if (_close_callback) _close_callback();
        }
        if (_event_callback) {
            _event_callback();
        }
    }
    uint32_t GetRevents() {return _revent;}
};

#define MAX_EVENT_SIZE 1024
class Poller
{
private:
    int _epfd;
    struct epoll_event _ev[MAX_EVENT_SIZE];
    std::unordered_map<int,Channel*> _channels;
private:
    std::string Op2String(int op){
        if (op == 1) return "EPOLL_CTL_ADD";
        else if(op == 2) return "EPOLL_CTL_DEL";
        else return "EPOLL_CTL_MOD";
    }
    void Update(Channel* channel,int op){
        struct epoll_event ev;
        ev.data.fd = channel->Fd();
        ev.events = channel->GetEvents();
        int ret = ::epoll_ctl(_epfd,op,channel->Fd(),&ev);   
        if (ret < 0){
            DBG_LOG("epfd:%d,fd:%d,op:%s",_epfd,channel->Fd(),Op2String(op).c_str());     
            ERR_LOG("UPDATE EVENTS ERROR!!!");
            ERR_LOG("错误原因：%s",strerror(errno));
            return;
        }
        return;
    }
    //存在返回true,不存在返回false
    bool IsHaveChannel(Channel* channel)
    {
        return _channels.find(channel->Fd()) != _channels.end();
    }

public:
    Poller(){
        memset(_ev,0,sizeof(_ev));
        //这里随便传入一个整数即可，必须 > 0
        _epfd = ::epoll_create(MAX_EVENT_SIZE);
        if (_epfd < 0){
            ERR_LOG("EPOLL CREATE ERROR!!!");
            abort(); //创建epoll模型失败直接不玩了，不能监控。
        }
    }
    void UpdateEvents(Channel* channel)
    {
        if (!IsHaveChannel(channel)){
            //不存在就添加
            _channels[channel->Fd()] = channel;
            // DBG_LOG("开始添加： %d", channel->Fd());
            return Update(channel,EPOLL_CTL_ADD);
        }
        //存在就修改
        return Update(channel,EPOLL_CTL_MOD);
    }
    void RemoveEvents(Channel* channel)
    {
        auto it = _channels.find(channel->Fd());
        if (it == _channels.end()){
            ERR_LOG("CHANNEL NOT FOUND!!");
            return;
        }
        //进行删除
        // DBG_LOG("开始移除： %d", channel->Fd());
        _channels.erase(it);
        return Update(channel,EPOLL_CTL_DEL);
    }
    //进行等待
    void Poll(std::vector<Channel*> *active){
        int nfds = ::epoll_wait(_epfd,_ev,MAX_EVENT_SIZE,-1);
        // DBG_LOG("nfds:%d",nfds);
        if (nfds < 0){
            ERR_LOG("EPOLL WAIT ERROR");
            perror("abort");
            abort();
        }
        // DBG_LOG("有几个活跃的事件: %d",nfds);
        //这里需要注意，得到之后直接通过 _channels获取对应的channels即可。
        for (int i = 0; i < nfds; i++){
            auto it = _channels.find(_ev[i].data.fd);
            assert (it !=_channels.end()); //如果没找到直接断言
            it->second->SetRevents(_ev[i].events);
            // DebugPrint(it->second);
            active->push_back(it->second); //然后添加进去
        }
    }
    ~Poller(){}
};
using TaskFunction = std::function<void()>;
using ReleaseFunction = std::function<void()>;
class TaskTimer
{
private:
    uint64_t _id;
    uint32_t _timeout;
    TaskFunction _task_cb;
    ReleaseFunction _release_cb;
    bool _cancle; //默认为false 表示没有被取消
public:
    TaskTimer(uint64_t id, uint32_t timeout, TaskFunction task_cb) : _id(id), _timeout(timeout), _task_cb(task_cb),_cancle(false)
    {
    }
    void SetRelease(const ReleaseFunction &cb)
    {
        _release_cb = cb;
    }
    void Cancle() {_cancle=true;}
    uint32_t DelayTime() { return _timeout; }
    ~TaskTimer()
    { // 时间轮通过释放智能指针，来执行析构函数，进行任务处理以及资源释放
        if (!_cancle) _task_cb();
        _release_cb();
    }
};
using PtrTimer = std::shared_ptr<TaskTimer>;
using WeakPtr = std::weak_ptr<TaskTimer>;
class TimerWheel
{
private:
    // C++类中初始化的顺序是我们定义的顺序
    int _capacity; // 时间轮的尺度 (大小)
    int _tick;     // 指针指向哪，就说明这个位置超时了，就要进行处理
    std::vector<std::vector<PtrTimer>> _wheel;
    std::unordered_map<uint64_t, WeakPtr> _timers;
    int _timerfd;
    //之后需要对事件进行监控，所以需要引入EventLoop
    EventLoop* _loop;
    std::unique_ptr<Channel> _timer_channel;
private:    
    static int CreateTimerfd(){
        int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
        if (timerfd < 0)
        {
            ERR_LOG("TIMERFD CREATE  FAILSE!!");
            //如果定时器创建失败了，就不玩了
            abort();
        }
        // DBG_LOG("get a timerfd: %d",timerfd);
        struct itimerspec itmes;
        itmes.it_value.tv_sec = 1;
        itmes.it_value.tv_nsec = 0; //设置第一个超时时间为多少，这里设置为1秒
        itmes.it_interval.tv_sec = 1;
        itmes.it_interval.tv_nsec = 0; //经过第一个超时时间后，多长时间超时一次，这里还是设置一秒
        timerfd_settime(timerfd,0,&itmes,NULL);
        return timerfd;
    }
    //这个只是为了把写入的次数清零，不然会一直触发写事件
    uint64_t ReadTimerfd(){
        uint64_t times = 0;
        int n = ::read(_timerfd,&times,sizeof(times)); 
        if (n< 0)
        {
            ERR_LOG("TIMERFD READ  FAILSE!!");
            //如果定时器创建失败了，就不玩了
            abort();
        }
        return times; 
    }
    void RunTimer()
    {
        _tick = (_tick + 1) % _capacity;
        // 把所有的数据清除，如果智能指针的引用计数减为0，就执行析构函数.
        _wheel[_tick].clear(); 
    }
    void OnTime(){
        // DBG_LOG("时钟递达了一下");
        uint64_t times = ReadTimerfd();
        //超时了多少次，就执行多少个超时任务
        for (int i = 0; i < times; i++){
            RunTimer();
        }
    }
    void TimerAddInLoop(uint64_t id, uint32_t delay,const TaskFunction& task_cb)
    {
        PtrTimer pt(new TaskTimer(id, delay, task_cb));
        pt->SetRelease(std::bind(&TimerWheel::Release, this, id));
        auto pos = (_tick + delay) % _capacity;
        _wheel[pos].push_back(pt);
        _timers[id] = pt; // 使用weak_ptr保存起来
    }    
      void TimerCancleInLoop(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            return;
        }
        //如果已经失效了，lock会返回一个空的shared_ptr
        PtrTimer pt = it->second.lock(); 
        if (pt) pt->Cancle(); 
    }
    void TimerRefreshInLoop(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            return;
        }
        PtrTimer pt = it->second.lock();
        // PtrTimer pt(it->second); // shared_ptr可以直接使用weak_ptr构造
        uint32_t delay = pt->DelayTime();
        // 从当前的指针开始延迟 delay 秒 再超时处理。没有问题奥。
        auto pos = (_tick + delay) % _capacity;
        _wheel[pos].push_back(pt);
    }

public:
    TimerWheel(EventLoop* loop) : _capacity(60), _tick(0), _wheel(_capacity),
        _loop(loop),
        _timerfd(CreateTimerfd()),
        _timer_channel(new Channel(loop,_timerfd)) //linux定时器 + 事件轮组合
    {
        _timer_channel->SetReadCallBack(std::bind(&TimerWheel::OnTime,this));
        //启动读事件
        _timer_channel->EnableReadEvent();
    }
    //这里需要注意，我们的添加/刷新/取消 都是会_timers进行操作，所以会存在线程安全问题
    //我们又不想加锁，所以要保证这些操作都是在EventLoop线程中执行，所以要添加到任务队列当中
    //由于EventLoop定义在下面，所以这些函数的定义放在了文件结尾
    void TimerAdd(uint64_t id, uint32_t delay, const TaskFunction& cb);
    void TimerCancle(uint64_t id);
    void TimerRefresh(uint64_t id);
    //需要注意这个也存在线程安全问题，所以我们在使用的时候要注意维持线程安全问题。
    //如果存在返回true,不存在返回false
    bool HasTimer(uint64_t id) {return _timers.find(id) != _timers.end();}
    ~TimerWheel() {}
private:
    void Release(uint64_t id)
    { //
        auto it = _timers.find(id);
        if (it != _timers.end())
        {
            _timers.erase(it);
        }
    }
};

class EventLoop
{
private:
    //为了避免等待事件到来被阻塞导致无法执行任务队列中的任务
    int _eventfd;
    using Functor = std::function<void()>;
    //任务队列，为什么要使用vector呢? 
    std::vector<Functor> _tasks;
    Poller _poller; //事件监控
    std::unique_ptr<Channel> _eventfd_channel;
    std::mutex _mutex; //对任务队列继续加锁 
    std::thread::id _thread_id; //存储当前进程的id值
    TimerWheel _wheel;
private:
    static int CreateEventfd(){
        int fd = eventfd(0,EFD_CLOEXEC | EFD_NONBLOCK);
        if (fd < 0){
            ERR_LOG("create fd error!!!");
            abort();
        }
        // DBG_LOG("get a eventfd: %d",fd);
        return fd;
    }
    void ReadEventfd(){
        uint64_t val = 0;
        int ret = ::read(_eventfd,&val,sizeof(val));
        if (ret < 0){
            if (errno == EAGAIN || errno == EINTR){
                return;
            }
            ERR_LOG("READ EVENTFD FAILSE!!");
            abort(); //读取失败说明 eventfd是无效的，那此时我就不玩了
        }
        return ;
    }
    void WakeUpPoller(){
        uint64_t val = 1;
        int ret = ::write(_eventfd,&val,sizeof(val));
        if (ret < 0){
            if (errno == EAGAIN || errno == EINTR){
                return;
            }
            ERR_LOG("WRITE EVENTFD FAILSE!!");
            abort(); //写失败说明 eventfd是无效的，那此时我就不玩了
        }
        return ;
    }
    void RunAllTasks(){
        std::vector<Functor> tmp;
        // DBG_LOG("开始执行任务");
        {
            //这就是lockguard，出了作用域自动释放锁
            std::unique_lock lock(_mutex);
            tmp.swap(_tasks);
        }
        // DBG_LOG("tmp.size(): %ld",tmp.size());
        //此时就可以直接运行了
        // sleep(1);
        for (auto& f : tmp){
            // DBG_LOG("开始执行任务");
            f();
        }
    }
public:
    EventLoop():_eventfd(CreateEventfd()),
        _eventfd_channel(new Channel(this,_eventfd)),
        _thread_id(std::this_thread::get_id()),
        _wheel(this)
    {
        //对eventfd进行监控，静态函数不需要绑定this指针。
        _eventfd_channel->SetReadCallBack(std::bind(&EventLoop::ReadEventfd,this)); 
        _eventfd_channel->EnableReadEvent();
    }
    //开始监控
    void Start()
    {
        while(1){
            //1. 进行事件监控
            std::vector<Channel*> active;
            _poller.Poll(&active);
            //2. 2. 就绪事件处理
            for (auto& a : active){
                a->HandlerEvent();
            }
            //3. 处理任务队列
            RunAllTasks();
            // sleep(1);
        }
    }
    //判断任务是否属于当前的线程
    bool IsInLooP()
    {
        //如果是当前线程返回true,不是返回false
        return _thread_id == std::this_thread::get_id();
    }
    //为切换协议单独设置的函数
    void AssertInLoop(){
        assert(_thread_id == std::this_thread::get_id());
    }
    //判断当前任务是否是当前线程执行，如果是直接执行，否则添加到任务队列当中
    void RunInLoop(const Functor&cb){
        if (IsInLooP()){
            //如果是当前的进程直接执行就可以了
            return cb();
        }
        return QueueInLoop(cb);
    }
    //把任务添加到任务队列当中
    void QueueInLoop(const Functor&cb)
    {
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _tasks.push_back(cb);
        }
        //但是这里为了避免Poll没有事件到来从而陷入阻塞，导致此时我们插入任务但是执行不了，所以我们需要使用eventf触发一个事件
        WakeUpPoller();
        return;
    }
    //1234\n
    //事件监控
    void UpdateEvents(Channel* channel) { _poller.UpdateEvents(channel);}
    void RemoveEvents(Channel* channel) {_poller.RemoveEvents(channel);}
    void TimerAdd(uint64_t id, uint32_t delay, const TaskFunction& cb){ _wheel.TimerAdd(id,delay,cb);}
    void TimerCancle(uint64_t id) { _wheel.TimerCancle(id);}
    void TimerRefresh(uint64_t id) { _wheel.TimerRefresh(id);}
    //使用需要注意
    bool IsHaveTimer(uint64_t id){return _wheel.HasTimer(id);}
};
class Any
{
    private:
        class Holder {
            public:
                virtual ~Holder(){}
                virtual const std::type_info& type() = 0; //获取子类存储的数据类型
                virtual Holder* clone() = 0; //通过子类在构建一个新的通用类型。 //??? 这个干什么的
        };
        template<class T>
        class placeholder : public Holder
        {
            public:
                placeholder(const T& val)
                    :_val(val)
                    {}
                virtual ~placeholder(){}
                //返回数据类型
                virtual const std::type_info& type() { return typeid(_val);} 
                //clone处一个新的对象返回回去
                virtual Holder* clone() { return new placeholder<T>(_val); } 
                T& GetVal() {return _val;}
            private:
                T _val; 
        };
        Holder* _con; 
    public:
        //无参数构造
        Any() :_con(nullptr)
            {} 
        ~Any()
        {
            if (_con)
            {
                delete _con;
                _con = nullptr;
            }
        }            
        //可以构造任意类型            
        template<class T> 
        Any(const T& val) 
            :_con(new Any::placeholder<T>(val))
            {} 

        Any(const Any&other)
            :_con(other._con->clone())
            {} //通过其他的any构造

        //获取子类存储的数据
        template<class T>
        T* get()
        {
            assert(typeid(T) == _con->type()); //如果你想要得到的值和我保存的值不一样直接断言
            return &(((placeholder<T>*)_con)->GetVal());
        } 
        //为了方便进行复制，我们添加一个swap函数
        Any& swap(Any&other){
            std::swap(_con,other._con);
            return *this;
        }
        //因为有无参的构造，所以需要让任意类型可以赋值
        template<class T> 
        Any& operator=(const T& val){
            return Any(val).swap(*this); //生成一个临时的Any对象，交换之后生命周期结束，然后自动释放掉。
        } 

        //通过其他的any赋值，默认的，如果不写的话，上面的模版不管用，会调用默认的赋值拷贝构造函数 (浅拷贝)
        Any& operator=(const Any&other)
        {
            return Any(other).swap(*this); 
        }  
};
//DISCONNECTED - 连接已经关闭，CONNECTING - 连接刚建立成功，回调函数还未设置
//CONNECTED - 连接的各种回调函数设置完毕，可以进行发送与接受数据饿了
//DISCONNECTING - 连接待关闭状态
typedef enum {DISCONNECTED,CONNECTING,CONNECTED,DISCONNECTING} ConnectStatus;
class Connection;
using PtrConnect = std::shared_ptr<Connection>;

class Connection : public std::enable_shared_from_this<Connection> 
{
    private:
        uint64_t _conn_id; //标识唯一性的ID，方便查找
        int _fd;           //连接fd
        ConnectStatus _status;  //连接的状态
        Socket _socket;    //接受与数据
        EventLoop* _loop; //连接所关联的EventLoop
        bool _enable_inactive_release;//启动与去掉非活跃释放
        Channel _channel; //连接管理
        Buffer _in_buffer; //接受缓冲区
        Buffer _out_buffer;//发送缓冲区
        Any _context;      //协议上下文
        using ConnectedCallBack = std::function<void(const PtrConnect&)>;
        using ClosedCallBack = std::function<void(const PtrConnect&)>;
        using MessageCallBack = std::function<void(const PtrConnect&,Buffer*)>;
        using AnyEventCallBack = std::function<void(const PtrConnect&)>;
        //阶段性回调函数，注意这里是提供给组件使用者的，跟我们的Channel的五个函数要区分开来。
        ConnectedCallBack _connected_callback;
        ClosedCallBack _closed_callback;
        MessageCallBack _message_callback;
        AnyEventCallBack _event_callback; 
        //未来我们会有服务器模块，他会把所有的连接进行管理，这个关闭操作是给服务器模块设置的。
        ClosedCallBack _srv_closed_callback;
    private:
        //Channel的五个回调函数
        void HandlerRead(){
            //1. 读取数据
            char buffer[65536] = {0};
            ssize_t ret  = _socket.RecvNonBlock(buffer,65535);
            // DBG_LOG("buffer: %s",buffer);
            if (ret < 0){
                //说明读取失败了，但是此时不能直接释放连接
                //看看缓冲区还有没有数据待处理
                return ShutdownInLoop();
            }
            //2. 调用_message_callback
            //如果ret==0，那么什么也不做
            _in_buffer.WriteAndPush(buffer,ret);
            if(_in_buffer.ReadAbleSize() > 0){
                //shared_from_this 需要继承enable_shared_from_this类，它内部回构建当前类的weak_ptr然后返回shared_ptr。
                return _message_callback(shared_from_this(),&_in_buffer);
            }
            return;
        }
        //实际释放连接的操作        
        void ReleaseInLoop(){
            //这里不需要特殊判断状态，如果是正常超时退出的话，是不会把状态改为DISCONNECTING的
            //1. 修改状态   
            _status = DISCONNECTED;
            //2. 移除链接
            _channel.Remove();
            // //3. 关闭连接 - 这里不能现在关闭，高并发的情况下可能出现问题。
            _socket.Close();
            //4. 如果超时队列有，取消非活跃连接释放操作
            if (_loop->IsHaveTimer(_conn_id)) CancelInactiveReleaseInLoop();
            //5.调用相关的回调函数
            //这里我们组件使用的要先关闭，防止服务端删除管理的连接之后，closed访问非法内存。
            if (_closed_callback) _closed_callback(shared_from_this());  //例如：我走了你们聊吧
            if (_srv_closed_callback)_srv_closed_callback(shared_from_this());
        }
        void HandlerWrite(){
            //1. 写数据
            ssize_t ret = _socket.SendNonBlock(_out_buffer.ReadPositoin(),_out_buffer.ReadAbleSize());
            //2. 判断
            if (ret < 0){
                //此时就需要关闭连接了，但是还需要判断一下读缓冲区中是否有数据待处理
                if (_in_buffer.ReadAbleSize() > 0){
                    _message_callback(shared_from_this(),&_in_buffer);
                }
                //此时就可以直接释放连接了
                return Release();
            }
            //如果ret==0的话，如果状态为待关闭则直接关闭，否则什么也不会发生。
            _out_buffer.ReadMoveOffset(ret);
            if (_out_buffer.ReadAbleSize() == 0){
                //如果没有数据发送了就可以关闭读事件了，不然每一次都要每监控到，浪费资源
                _channel.DelWriteEvent(); 
                if (_status == DISCONNECTING){
                    //如果此时正好处于待关闭状态，直接释放
                    return Release();
                }
            }
            return;
        }
        void HandlerClose(){
            //此时就需要关闭连接了，但是还需要判断一下读缓冲区中是否有数据待处理
            if (_in_buffer.ReadAbleSize() > 0){
                _message_callback(shared_from_this(),&_in_buffer);
            }
            //此时就可以直接释放连接了
            return Release();
        }
        void HandlerError(){
            HandlerClose();
        }   
        //1.延迟超时 2. 执行组件使用者设置的任意事件回调函数
        void HandlerEvent(){
            if (_enable_inactive_release == true){_loop->TimerRefresh(_conn_id);}
            if (_event_callback) {_event_callback(shared_from_this());}
        }
        //CONNECTING需要进行的操作
        void EstablishedInLoop()
        {
            //1. 修改连接状态 2. 启动读事件 3. 调用回调函数
            assert(_status == CONNECTING);
            _status = CONNECTED;
            _channel.EnableReadEvent();
            if (_connected_callback) _connected_callback(shared_from_this());
        }
        //注意这里并不是直接发送数据，而是放到发送缓冲区当中，然后启动些时间
        void SendInLoop(Buffer& buff){
            //如果状态是已经关闭的，则直接返回
            if (_status == DISCONNECTED) return;
            _out_buffer.WriteAsBufferPush(buff);
            //如果没有启动写事件再启动
            if (_channel.IfWriteEvent() == false){
                _channel.EnableWriteEvent();
            }
            return;
        }
        //这里并不是真正的关闭连接，而是看缓冲区中是否有数据待处理,并且还要修改状态为DISCONNECTING
        void ShutdownInLoop()
        {
            //修改状态为半关闭状态
            _status = DISCONNECTING;
            if (_in_buffer.ReadAbleSize() > 0){
                if (_message_callback) _message_callback(shared_from_this(),&_in_buffer);
            }
            //如果发送缓冲区中还有数据就启动写事件
            if (_out_buffer.ReadAbleSize() > 0){
                if (_channel.IfWriteEvent() == false){
                    _channel.EnableWriteEvent();
                }
            }
            //如果此时没有数据了，直接释放连接即可。
            if (_out_buffer.ReadAbleSize() == 0){
                Release();
            }
            return; 
        }
         //启动非活跃释放
        void EnabelInactiveReleaseInLoop(int sec){
            _enable_inactive_release = true;
            //如果存在就刷新，不存在就创建
            if (_loop->IsHaveTimer(_conn_id)){
                return _loop->TimerRefresh(_conn_id);
            }
            _loop->TimerAdd(_conn_id,sec,std::bind(&Connection::Release,this));
        }
        //取消非活跃释放
        void CancelInactiveReleaseInLoop(){
            _enable_inactive_release = false;
            //如果存在就取消
            if (_loop->IsHaveTimer(_conn_id)){
                _loop->TimerCancle(_conn_id);
            }  
        }
        //协议切换
        void UpgradeInLoop(const Any& context,const ConnectedCallBack& conn_cb,
            const ClosedCallBack& close_cb,const MessageCallBack& mess_cb,
            const AnyEventCallBack& ev_cb){
                _context = context;
                _connected_callback = conn_cb;
                _closed_callback = close_cb;
                _message_callback = mess_cb;
                _event_callback = ev_cb;
            }           
    public:
        Connection(EventLoop*loop,uint64_t conn_id,int fd)
            :_loop(loop),
	        _conn_id(conn_id),
	        _fd(fd),
	        _enable_inactive_release(false),
	        _status(CONNECTING),
            _channel(_loop,_fd),_socket(fd)
        {
            // DBG_LOG("NEW channle fd is: %d",_channel.Fd());
            //设置5个回调函数
            _channel.SetReadCallBack(std::bind(&Connection::HandlerRead,this));
            _channel.SetWriteCallBack(std::bind(&Connection::HandlerWrite,this));
            _channel.SetCloseCallBack(std::bind(&Connection::HandlerClose,this));
            _channel.SetErrorCallBack(std::bind(&Connection::HandlerError,this));
            _channel.SetEventsCallBack(std::bind(&Connection::HandlerEvent,this));
            // DBG_LOG("new connection: %p",this);
        }    
        ~Connection(){DBG_LOG("release connection: %p",this);};    
        //获取文件描述符
        int Fd() {return _fd;}
        //获取连接id
        uint64_t Id(){return _conn_id;} 
        //获取连接的状态
        ConnectStatus Status() {return _status;}
        //设置上下文
        void SetContext(const Any& context){_context = context;}
        //获取上下文，要保证操作的是同一个上下文
        Any* Getontext(){return &_context;}
        //设置回调函数
        void SetConnectedCallback(const ConnectedCallBack& conn) {_connected_callback = conn;}
        void SetClosedCallBack(const ClosedCallBack& closed){_closed_callback = closed;}
        void SetMessageCallBack(const MessageCallBack& mess){_message_callback = mess;}
        void SetAnyEventCallBack(const AnyEventCallBack& event) {_event_callback = event;}
        void SetSrvClosedCallBack(const ClosedCallBack& srv_closed) {
            _srv_closed_callback = srv_closed;
        }
        //发送数据
        void Send(const void* data,uint32_t len){
            Buffer buff;
            buff.WriteAndPush(data,len);
            return _loop->RunInLoop(std::bind(&Connection::SendInLoop,this,std::move(buff))); 
        }
        //关闭连接
        void Shutdown(){
            return _loop->RunInLoop(std::bind(&Connection::ShutdownInLoop,this)); 
        }
        void Release(){
            return _loop->QueueInLoop(std::bind(&Connection::ReleaseInLoop,this));
        }
        //设置Channel的回调函数，启动写事件，调用connected_callback
        void Established() {return _loop->RunInLoop(std::bind(&Connection::EstablishedInLoop,this)); }
        //启动非活跃释放
        void EnabelInactiveRelease(int sec){return _loop->RunInLoop(std::bind(&Connection::EnabelInactiveReleaseInLoop,this,sec)); }
        //取消非活跃释放
        void CancelInactiveRelease() {return _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop,this)); }
        //协议切换 - 这里需要注意切换协议的操作，必须在线程中立即被执行!!
        void Upgrade(const Any& context,const ConnectedCallBack& conn_cb,
            const ClosedCallBack& close_cb,const MessageCallBack& mess_cb,
            const AnyEventCallBack& ev_cb) {
                //处理这个函数的必须是原来的线程，防止新的事件到来之后，数据处理还是使用的原来的业务处理函数！！！
                _loop->AssertInLoop();
                return _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop,this,context,conn_cb,close_cb,mess_cb,ev_cb));
            }
};


class Acceptor
{
private:
    Socket _socket; //创建监听套接字
    EventLoop* _loop; //对连接的事件进行监控
    Channel _channel; //对连接的事件管理
    int CreateServer(uint16_t port){
        bool ret = _socket.CreateServer(port);
        //如果创建失败了就不继续运行了。
        assert(ret == true); 
        return _socket.Fd();
    }
    using AcceptorCallBack = std::function<void(int)>;
    //对新连接的操作
    AcceptorCallBack _acceptor_callback;
    void HandlerRead(){
        int fd = _socket.Accept();
        if (fd < 0){
            ERR_LOG("ACCETOR FAIL!");
            //直接退出就可以了
            return; 
        }
        if (_acceptor_callback) _acceptor_callback(fd);
    }
public:
    Acceptor(EventLoop* loop, uint16_t port):
        _socket(CreateServer(port)),_loop(loop),_channel(loop,_socket.Fd())
        {
            _channel.SetReadCallBack(std::bind(&Acceptor::HandlerRead,this));
        }
    void SetAcceptorCallBack(const AcceptorCallBack& cb) {_acceptor_callback = cb;}
    void Listen(){ 
        _channel.EnableReadEvent();
    }
    ~Acceptor(){}
};

class LoopThread
{
private:
    std::thread _thread;
    //在线程的入口函数进行初始化
    EventLoop* _loop;  
    /*如果在我们创建线程之后，示例话loop对象之前要获取*loop呢? 
    但是此时还没有实例化啊，所以我们需要保证这个顺序性，如果想要获取*loop的时候还没有实例化就等着。*/
    std::mutex _mutex;
    std::condition_variable _cond;
    void ThreadEntry(){
        EventLoop loop; 
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _loop = &loop;  
           _cond.notify_all();                 
        }
        //我们希望loop的生命周期有线程控制，线程退出，loop才释放,所以这里采用局部变量
        loop.Start();
    }
public:
    LoopThread() :_loop(nullptr),_thread(std::thread(&LoopThread::ThreadEntry,this))
        {}
    EventLoop* GetEventLoop(){
        EventLoop* loop = nullptr;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            //只有当_loop不为空的时候才可以获取，否则就被阻塞住
            _cond.wait(lock,[&](){return _loop != nullptr;});
            loop = _loop;
        }
        return loop; 
    }
    ~LoopThread(){}
};

class LoopThreadPool
{
private:
    int _threads_count;                 //LoopThread数量
    int _nxt_loop_idx;                  //下一个分配的EventLoop    
    EventLoop* _baseloop;               //主EventLoop
    std::vector<LoopThread*> _threads;  //对LoopThread进行管理
    std::vector<EventLoop*> _loops;     //对从EventLoop进行管理
public:
    LoopThreadPool(EventLoop* baseloop):_threads_count(0),_nxt_loop_idx(0),_baseloop(baseloop)
        {}
    //设置LoopThread数量
    void SetLoopThreadCount(int count) {_threads_count = count;}
    //创建线程池 - 对vector进行初始化
    void CreateLoopThreadPool(){
        if (_threads_count > 0){
            _threads.resize(_threads_count);
            _loops.resize(_threads_count);
            for (int i = 0; i < _threads_count; i++){
                _threads[i] = new LoopThread();
                _loops[i] = _threads[i]->GetEventLoop();
            }
        }
        return;
    }
    //获取下一个从EventLoop
    EventLoop* NextLoop(){
        if (_threads_count == 0) return _baseloop;
        _nxt_loop_idx = (_nxt_loop_idx + 1) % _threads_count;
        return _loops[_nxt_loop_idx];
    }
};

class TcpServer
{
private:
    uint64_t _next_id;                                  //conn_Id和超时任务队列id
    uint16_t _port;
    int _timeout;                                       //超时的时间
    bool _enable_inactive_release;                      //是否启动非活跃释放
    EventLoop _baseloop;                                //主Reactor
    Acceptor _acceptor;                                 //监听模块
    std::unordered_map<uint64_t,PtrConnect> _conns;     //管理每一个连接
    LoopThreadPool _pool;                               //线程池
    using ConnectedCallBack = std::function<void(const PtrConnect&)>;
    using ClosedCallBack = std::function<void(const PtrConnect&)>;
    using MessageCallBack = std::function<void(const PtrConnect&,Buffer*)>;
    using AnyEventCallBack = std::function<void(const PtrConnect&)>;
    //阶段性回调函数，注意这里是提供给组件使用者的，跟我们的Channel的五个函数要区分开来。
    ConnectedCallBack _connected_callback;
    ClosedCallBack _closed_callback;
    MessageCallBack _message_callback;
    AnyEventCallBack _event_callback;     
    using Functor = std::function<void()>;
private:
    void RemoveInLoop(const PtrConnect& conn){
        int fd = conn->Id();
        auto it = _conns.find(fd);
        if (it != _conns.end()){
            _conns.erase(it);
            return;
        }
        return;
    }
    //移除在_conns中管理的connection ，这个需要在各自线程内部执行
    void Remove(const PtrConnect& conn){
        return _baseloop.RunInLoop(std::bind(&TcpServer::RemoveInLoop,this,conn));
    }
    void NewConnection(int newfd){
        _next_id++;
        // DBG_LOG("newfd is %d", newfd);
        PtrConnect con(new Connection(_pool.NextLoop(),_next_id,newfd));
        con->SetConnectedCallback(_connected_callback);
        con->SetClosedCallBack(_closed_callback);
        con->SetMessageCallBack(_message_callback);
        con->SetSrvClosedCallBack(std::bind(&TcpServer::Remove,this,std::placeholders::_1));
        //只有当用户启动了非活跃销毁才启动
        if (_enable_inactive_release) con->EnabelInactiveRelease(_timeout);
        con->Established(); //修改状态，启动读事件
        _conns.insert(std::make_pair(_next_id,con));
    }
    void RunAfterInLoop(const Functor& cb,uint32_t delay){
        _next_id++;
        return _baseloop.TimerAdd(_next_id,delay,cb);
    }
public:
    TcpServer(uint16_t port) 
        :_port(port),
        _next_id(0),
        _enable_inactive_release(false),
        _acceptor(&_baseloop,_port),
        _pool(&_baseloop)
        {
            //设置监听回调函数，启动监听
            _acceptor.SetAcceptorCallBack(std::bind(&TcpServer::NewConnection,this,std::placeholders::_1));
            _acceptor.Listen();
        }
    void SetThreadCount(int count) {_pool.SetLoopThreadCount(count);}
    //设置回调函数
    void SetConnectedCallback(const ConnectedCallBack& conn) {_connected_callback = conn;}
    void SetClosedCallBack(const ClosedCallBack& closed){_closed_callback = closed;}
    void SetMessageCallBack(const MessageCallBack& mess){_message_callback = mess;}
    void SetAnyEventCallBack(const AnyEventCallBack& event) {_event_callback = event;}    
    void EnableInactiveRelease(int timeout){
        _timeout = timeout;
        _enable_inactive_release = true;
    }
    //添加超时任务，这个也是要再各个线程内部执行,如果用到的话    
    void RunAfter(const Functor& cb,uint32_t delay){
        return _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop,this,cb,delay));
    }
    //启动服务器    
    void Start(){
        //此时回调都设置完毕了，线程数量也设置完毕了，就可以创建线程池，直接启动了
        _pool.CreateLoopThreadPool();
        _baseloop.Start();
    } 
};
//Channel模块中需要调用Poller模块方法的函数的定义
void Channel::Update() { _loop->UpdateEvents(this);}
void Channel::Remove() {_loop->RemoveEvents(this);}
void TimerWheel::TimerAdd(uint64_t id, uint32_t delay, const TaskFunction& cb){
    _loop->RunInLoop(std::bind(&TimerWheel::TimerAddInLoop,this,id,delay,cb)); 
}
void TimerWheel::TimerCancle(uint64_t id){ 
    _loop->RunInLoop(std::bind(&TimerWheel::TimerCancleInLoop,this,id)); 
}
void TimerWheel::TimerRefresh(uint64_t id){
    _loop->RunInLoop(std::bind(&TimerWheel::TimerRefreshInLoop,this,id));         
}    
void DebugPrint(Channel* channel){
    uint32_t revent = channel->GetRevents();
    std::cout << "#####################################################" << std::endl;
    std::cout << "当前的fd: " << channel->Fd();
    std::cout << "是否触发EPOLLIN: " << ((revent&EPOLLIN) == EPOLLIN) << std::endl;
    std::cout << "是否触发EPOLLOUT: " << ((revent&EPOLLOUT) == EPOLLOUT) << std::endl;
    std::cout << "是否触发EPOLLHUP: " << ((revent&EPOLLHUP) == EPOLLHUP) << std::endl;
    std::cout << "EPOLLERR: " << ((revent&EPOLLERR) == EPOLLERR) << std::endl;
    std::cout << "#####################################################" << std::endl;
    sleep(1);
}

class NetWork
{
public:
    NetWork(){
        DBG_LOG("SIGPIPE INIT");
        signal(SIGPIPE,SIG_IGN);
    }
};
static NetWork nw;
